/** ****************************************************************************
@addtogroup CtlLight
@{
*******************************************************************************/

#include "ctl_light.h"

#define LOGTAG "CTL_LIGHT"

void ctl_light_init(driver_ctl_light_t* dev, FUNC_GPIO_PwmSetDuty funcCoolPwmSetDuty, FUNC_GPIO_PwmSetDuty funcWarmPwmSetDuty) {
	dev->funcCoolPwmSetDuty	= funcCoolPwmSetDuty;
	dev->funcWarmPwmSetDuty	= funcWarmPwmSetDuty;
	dev->lightness = 0;
	dev->temperature = 0x7FFF;
	dev->blinkTaskId = NULL;
	dev->blinkExOnTime = 0;
}

bool ctl_light_set_lightness(driver_ctl_light_t* dev, uint16_t lightness) {
	return ctl_light_set(dev, dev->temperature, lightness);
}

bool ctl_light_set_temperature(driver_ctl_light_t* dev, uint16_t temperature) {
	return ctl_light_set(dev, temperature, dev->lightness);
}

bool ctl_light_set(driver_ctl_light_t* dev, uint16_t temperature, uint16_t lightness) {
	bool changed = (lightness == dev->lightness); dev->lightness = lightness;
	changed = (temperature == dev->temperature); dev->temperature = temperature;	

	// 计算冷暖光的 duty
	uint8_t coolDuty, warmDuty;
	if(temperature >= CTL_TEMP_NORMAL) {
		coolDuty = (lightness * 100) >> 16; // 偏冷色，冷色的亮度做为基准值
		warmDuty = coolDuty * (2.0 - 1.0*temperature / CTL_TEMP_NORMAL);
	} else {
		warmDuty = (lightness * 100) >> 16; // 偏暖色，暖色的亮度做为基准值
		coolDuty = warmDuty * (1.0*temperature / CTL_TEMP_NORMAL);
	}
	
	dev->funcCoolPwmSetDuty(coolDuty);
	dev->funcWarmPwmSetDuty(warmDuty);
	logd("ctl_light_set(): temp/light = %d/%04X, cool/warm = %d/%d\r\n", temperature, lightness, coolDuty, warmDuty);
	
	return changed;
}

bool ctl_light_switchTo(driver_ctl_light_t* dev, switch_state_t state, uint32_t keepTime1, uint32_t keepTime2, uint8_t flashTimes) {
    // 如果之前已经调过 blinkEx() ，则取消之前的
    ctl_light_blinkStop(dev);

    if(state == SWITCH_OFF) {
        return ctl_light_off(dev);
    } else if(state == SWITCH_ON) {
        return ctl_light_on(dev);
    } else if(state == SWITCH_TOGGLE) {
        ctl_light_toggle(dev);
		return true;
    } else if(state == SWITCH_BLINK) {
        ctl_light_blinkEx(dev, keepTime1, keepTime2, flashTimes);
    }
    return false;
}

static void blinkHandler(uint8_t len, void* data) {
	driver_ctl_light_t* dev = (driver_ctl_light_t*)getPointer(data);
	ctl_light_off(dev);
}

void ctl_light_blink(driver_ctl_light_t* dev, uint16_t time) {
	ctl_light_on(dev);
	osTaskRunAfter(time, blinkHandler, sizeof(void*), &dev);
}

static void blinkExHandler(uint8_t len, void* data) {
	driver_ctl_light_t* dev = (driver_ctl_light_t*)getPointer(data);
	ctl_light_blink(dev, dev->blinkExOnTime);
}

uint16_t ctl_light_blinkEx(driver_ctl_light_t* dev, uint16_t onTime, uint16_t offTime, uint16_t count) {
	// 参数检查
	if(!(onTime && offTime && count>1)) { return NULL; }
    dev->blinkExOnTime = onTime;

    // 如果之前已经调过 blinkEx() ，则取消之前的
    osTaskDestroy(&dev->blinkTaskId);

    // 先闪第一次
    ctl_light_blink(dev, onTime);
    if(count != OSTASK_REPEAT_FOREVER) { count--; }

	// 安排后续的闪烁
	// 注意：需要把对象的指针传过去，以便在回调函数中访问对象
	return dev->blinkTaskId = osTaskRunEvery(onTime+offTime, count, blinkExHandler, sizeof(dev), &dev);
}


/// @}
